﻿#include "EditorMaterialPreviewAbilityView.h"

#include "Scene/Scene.h"

#include "Widgets/ViewportWidget.h"
#include "Widgets/Mouse/MouseWidget.h"
#include "Widgets/TextWidget.h"

void REditorMaterialPreviewAbilityView::CreateWidget(TSharedObjectPtr<RWidget> InParent)
{
    auto Root=NewWidget<RWidget>(InParent);
    Root->Anchor.Fill(InParent);

    auto EmptyText=NewWidget<RTextWidget>(Root);
    EmptyText->Text=U"没有材质可供预览";
    EmptyText->Anchor.CenterIn(Root);
    EmptyText->Visible=[this]()->bool
    {
        return !MaterialPreviewViewModel->HasPreviewMaterial();
    };

    auto PreviewViewport=NewWidget<RViewportWidget>(Root);
    PreviewViewport->SetScene(MaterialPreviewViewModel->PreviewScene);
    PreviewViewport->Anchor.Fill(Root);
    PreviewViewport->bForceUseDefaultParameters=true;
    PreviewViewport->Visible=[this]()->bool
    {
        return MaterialPreviewViewModel->HasPreviewMaterial();
    };


    //calculate the position and rotation of the camera
    static const float DistanceToPreviewMesh=5.0f;
    static float Pitch=CMathBase::DegreeToRadian(-45.f);
    static float Yaw=0;

    
    RViewportWidgetWeakPtr PreviewViewportWeak=PreviewViewport;
    PreviewViewport->ViewportRotation=[this]()->SQuat
    {
        return SQuat::FromEuler(SVec3(Pitch,0,Yaw));
    };

    PreviewViewport->ViewportPosition=[this,PreviewViewportWeak]()->SVec3
    {
        return PreviewViewportWeak->ViewportRotation.Get().GetForwardDirection()*-DistanceToPreviewMesh;
    };


    //create a widget to let user to rotate view
    auto Mouse =NewWidget<RMouseWidget>(Root);
    Mouse->Anchor.Fill(Root);
    Mouse->Visible=[this]()->bool
    {
        return MaterialPreviewViewModel->HasPreviewMaterial();
    };

    Mouse->Drag->bIsEnabled=true;

    //you cant drag the mouse on two widgets at the same time
    //so use a static variable is safe
    static float InitPitch=0;
    static float InitYaw=0;

    Mouse->Drag->OnDragStarted.Bind([this]()
    {
        InitPitch=Pitch;
        InitYaw=Yaw;
    });

    Mouse->Drag->OnDragMoved.Bind([PreviewViewportWeak](const SVec2& MouseDelta )
    {
        float DeltaPitch= -MouseDelta.Y*0.01f;
        Pitch=CMath::Clamp(InitPitch+DeltaPitch, -CMathBase::HalfPi,0);
        Yaw=InitYaw-MouseDelta.X*0.01f;
    });
}

void REditorMaterialPreviewAbilityView::BindViewModel(TSharedObjectPtr<REditorAbilityViewModel> InViewModel)
{
    Super::BindViewModel(InViewModel);
    MaterialPreviewViewModel = InViewModel;
}

void REditorMaterialPreviewAbilityView::FillOperations(TSharedObjectPtr<RWidget> InTitleBar)
{
    //no operations for now
}
